<!DOCTYPE html>

<html>
    <head>
        <meta charset="UTF-8">
        <title>事件处理程序</title>
    </head>
    <body>

        <script type="text/javascript">
            function hello(){
                console.log( arguments );
                // 获得当前函数的引用(当前函数是谁就获得谁)
                let self = arguments.callee ; 
                console.log( self );
                // 获得当前函数的调用者
                let caller = self.caller ; // Function.prototype.caller
                console.log( caller );
                // 获得 caller 函数的实参列表
                let args = caller.arguments ;
                console.log( args );
                // 从 caller 函数的实参列表中获取事件实例
                let event = args[ 0 ];
                console.log( event );
            }
        </script>
        <!-- 将事件写在元素的开始标签中，当作元素的属性来使用 -->
        <button type="button" onclick="hello()">HTML事件处理程序</button>
        <ul>
            <li>事件处理程序 与 事件目标(比如某个元素)耦合度太高</li>
            <li>寻找事件对象(event)时比较麻烦(本例中点击事件发生后首先调用onclick函数，再调用hello函数)</li>
            <li>仅能为同一个事件绑定一个事件处理程序</li>
        </ul>
        
        <button type="button" class="second">DOM 0 事件处理程序</button>
        <script type="text/javascript">
            const s = document.querySelector( '.second' );
            // 通过 onclick 形式绑定事件处理程序
            s.onclick = function() {
                console.log( arguments );
                console.log( arguments[ 0 ] );
            }
        </script>
        <ul>
            <li>事件处理程序 与 事件目标 解耦合</li>
            <li>直接通过被指定函数的第一个实参来获得事件对象</li>
            <li>仅能为同一个事件绑定一个事件处理程序</li>
        </ul>

        <button type="button" class="third">DOM 2 事件处理程序</button>

        <script type="text/javascript">
            const t = document.querySelector( '.third' );
            // 指定事件名称(也称作事件类型)
            const type = 'click' ;
            // 监听器可以是一个函数
            const listener1 = function(){
                console.log( arguments );
            }
            const useCapture = false ;
            // 为 t 绑定 type 事件处理程序( listener1 )
            t.addEventListener( type , listener1 , useCapture );
            // 监听器可以是一个含有 handleEvent 函数的对象(实例级别)
            const listener2 = {
                handleEvent(){
                    console.log( arguments );
                }
            }
            // 为 t 绑定 type 事件处理程序( listener2 )
            t.addEventListener( type , listener2 , useCapture );
        </script>

        
    </body>
</html>